package testing;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Scanner;

import fileDistributionStatistics.FileSizeDistributionCalculation;
import fileDistributionStatistics.FileSizeInfo;

public class WastageSpaceHelper {
	
	File fFile;
	File parseFilename = new File(
			"/home/bhavya/Desktop/BHAVYA_FYP/Cloud_Computing_FYP/FileSizeDistributionStatistics/CalculatedfileSizeGreatertan1byte.txt");
	int startingFileSize = 0;
	int sumOfSmallFileSizes = 0;
	int startingSourceFragNum=0;
	List<FileSizeInfo> fileInfo = new ArrayList<FileSizeInfo>();
	List<Integer> numOfServers;
	

	public int getStartingFileSize() {
		return startingFileSize;
	}

	public void setStartingFileSize(int startingFileSize) {
		this.startingFileSize = startingFileSize;
	}

	public WastageSpaceHelper() {

		startingFileSize = 40 * 1024;
		fFile = parseFilename;
		startingSourceFragNum=128;
		try{
			processLineByLine();
		}catch(Exception e){
			e.printStackTrace();
		}
		preProcessFileSize();
		
	}
	
	/***
	 * 
	 * @param startingSrcFragNum
	 */

	public double calculateCumSpace(int wastageSpace) {
		numOfServers= new ArrayList<Integer>();
		return(calculateFragmentSize(wastageSpace));
	}
	
	public int calculateMaxServer(){
		int max=Collections.max(numOfServers);
//		System.out.println(max);
		numOfServers=null;
		return(max);
	}
	/**
	 * 
	 * @throws FileNotFoundException
	 */

	public final void processLineByLine() throws FileNotFoundException {
		// Note that FileReader is used, not File, since File is not Closeable
		Scanner scanner = new Scanner(new FileReader(fFile));
		try {

			// first use a Scanner to get each line
			while (scanner.hasNextLine()) {
				processLine(scanner.nextLine());
			}
		} finally {
			scanner.close();
		}
	}

	/***
	 * 
	 * @param aLine
	 */
	
	
	protected void processLine(String aLine) {
		// use a second Scanner to parse the content of each line
		Scanner scanner = new Scanner(aLine);

		int rep1=0;
		scanner.useDelimiter(":");
		if (scanner.hasNext()) {
			String fs = scanner.next().trim();
			String rep = scanner.next().trim();
			rep1 = Integer.parseInt(rep);
			fileInfo.add(new FileSizeInfo(Double.parseDouble(fs), Integer
					.parseInt(rep)));
		}
		scanner.close();
	}

	/***
	 * 
	 */
	
	
	public void preProcessFileSize() {
		for (int i = 0; i < fileInfo.size(); i++) {
			double fs = fileInfo.get(i).getFileSize();
			if (fs <= startingFileSize) {
				sumOfSmallFileSizes += (fs * fileInfo.get(i).getNumberOfFiles());
			}
		}
		int numberOf40KB = (int) Math.ceil((double) sumOfSmallFileSizes
				/ startingFileSize);
		int index = 0;
		for (int i = 0; i < fileInfo.size(); i++) {
			if (fileInfo.get(i).getFileSize() == startingFileSize) {
				index = i;
				break;
			}
		}
		
		if (index != 0) {
			int existingNumberOf40KB = fileInfo.get(index).getNumberOfFiles();
			fileInfo.get(index).setNumberOfFiles(
					existingNumberOf40KB + numberOf40KB);
		} else {
			fileInfo.add(new FileSizeInfo((double) startingFileSize,
					numberOf40KB));
		}
		
//		int i = 0;
//		while (fileInfo.size() != 0) {
//			double fs = fileInfo.get(i).getFileSize();
//			if (fs < startingFileSize) {
//				fileInfo.remove(i);
//				i = 0;
//			} else {
//				i++;
//			}
//
//			if (i == fileInfo.size()) {
//				break;
//			}
//		}
		
//		for (i = 0; i < fileInfo.size(); i++) {
//			if (fileInfo.get(i).getFileSize() == getStartingFileSize()) {
//				System.out.println(" 40 kb source file"
//						+ fileInfo.get(i).getFileSize() + "no of copies"
//						+ fileInfo.get(i).getNumberOfFiles());
//			}
//		}

	}
	
	/***
	 * 
	 * @param startingSrcFragNum
	 */
	

	private double calculateFragmentSize(int wastageSpace) {
		FileSizeDistributionCalculation f = new FileSizeDistributionCalculation();
        double cumSpaceOccupied=0;
		for (int i = 0; i < fileInfo.size(); i++) {
			double source_file = fileInfo.get(i).getFileSize();
			int rep = fileInfo.get(i).getNumberOfFiles();
			
			if(source_file>=startingFileSize){			
			f.setNumberOfSourceFragments(startingSourceFragNum);
			f.setWASTAGEVALUE(wastageSpace);
			f.setSourceFileLength((double) Math.abs(source_file * rep));
//			System.out.println(f.getSourceFileLength());
			f.setSourceFileLength(f.getSourceFileLength());

			f.setFragmentSize(f.calculateFragmentSize());
			
			double totalEncodedSpaceOccupied = f.setParameters();
			
			
			
//			double factor = f.getSourceFileLength() % 4096;
//			double sourceFileDiskSpaceOccupied = f.getSourceFileLength();
//			if (factor != 0) {
//				sourceFileDiskSpaceOccupied = f.getSourceFileLength()
//						+ (4096 - factor);
//			}
			
			numOfServers.add(f.getNumberOfSourceFragments());
			cumSpaceOccupied+=totalEncodedSpaceOccupied;
			
			}
		}
//		System.out.println(Collections.max(numOfServers));
		return cumSpaceOccupied;
	}
	
	
	
	
	

}
